package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"os"
	"xorm.io/xorm"
	"xorm.io/xorm/log"
)

// 创建 Engine:https://xorm.io/zh/docs/chapter-01/1.engine/
// 所有操作均需要事先创建并配置 ORM 引擎才可以进行。XORM 支持两种 ORM 引擎，即 Engine 引擎和 Engine Group 引擎。
// 一个 Engine 引擎用于对单个数据库进行操作，一个 Engine Group 引擎用于对读写分离的数据库或者负载均衡的数据库进行操作。
// Engine 引擎和 EngineGroup 引擎的API基本相同，所有适用于 Engine 的 API 基本上都适用于 EngineGroup，
// 并且可以比较容易的从 Engine 引擎迁移到 EngineGroup 引擎。
func main() {
	//connectDb01()
	//connectDb02()
	connectDb03()
}

// connectDb01
//
//	@Description: 一般情况下如果只操作一个数据库，只需要创建一个 engine 即可。engine 是 GoRoutine 安全的。
func connectDb01() {
	var engine *xorm.Engine
	var err error
	var dns string = "root:root123@tcp(127.0.0.1:3306)/xorm1?charset=utf8mb4&parseTime=True&loc=Local"
	engine, err = xorm.NewEngine("mysql", dns)
	if err != nil {
		panic(err)
	}
	//创建完成 engine 之后，并没有立即连接数据库，此时可以通过 engine.Ping() 或者 engine.PingContext() 来进行数据库的连接测试是否可以连接到数据库。
	err = engine.Ping()
	if err != nil {
		panic(err)
	}
	defer engine.Close()
	fmt.Printf("数据库连接成功:%s \n", dns)
	f, err := os.Create("sql.log")
	engine.SetLogger(log.NewSimpleLogger(f))
	engine.SetLogLevel(log.DEFAULT_LOG_LEVEL)

}

// connectDb02
//
//	@Description: 对于有大量数据并且需要分区的应用，也可以根据规则来创建多个Engine，
func connectDb02() {
	var engine []*xorm.Engine = make([]*xorm.Engine, 3)

	var dns string = "root:root123@tcp(127.0.0.1:3306)/xorm%d?charset=utf8mb4&parseTime=True&loc=Local"
	for i := 0; i < 3; i++ {
		var err error
		engine[i], err = xorm.NewEngine("mysql", fmt.Sprintf(dns, i+1))
		if err != nil {
			panic(err)
		}
		defer engine[i].Close()
		err = engine[i].Ping()
		if err != nil {
			panic(err)
		}
		fmt.Printf("数据库连接成功:%s \n", fmt.Sprintf(dns, i))

	}
}

// connectDb03
//
//	@Description: 日志是一个接口，通过设置日志，可以显示SQL，警告以及错误等，默认的显示级别为 INFO。
//
// 日志是一个接口，通过设置日志，可以显示SQL，警告以及错误等，默认的显示级别为 INFO。
//
// engine.ShowSQL(true)，则会在控制台打印出生成的SQL语句；
// engine.Logger().SetLevel(log.LOG_DEBUG)，则会在控制台打印调试及以上的信息；
// 如果希望将信息不仅打印到控制台，而是保存为文件，那么可以通过类似如下的代码实现，NewSimpleLogger(w io.Writer)接收一个io.Writer接口来将数据写入到对应的设施中。
func connectDb03() {
	var dns string = "root:root123@tcp(127.0.0.1:3306)/xorm1?charset=utf8mb4&parseTime=True&loc=Local"
	engine, err := xorm.NewEngine("mysql", dns)
	if err != nil {
		panic(err)
	}
	err = engine.Ping()
	if err != nil {
		panic(err)
	}
	defer engine.Close()
	//打印日志到控制台
	engine.ShowSQL(true)
	engine.Logger().SetLevel(log.LOG_DEBUG)

	//将日志保存到文件
	f, err := os.Create("sql.log")
	if err != nil {
		println(err.Error())
		return
	}
	engine.SetLogger(log.NewSimpleLogger(f))

}

// connectDb04
//
//	@Description:连接池
//
// 如果需要设置连接池的空闲数大小，可以使用 engine.SetMaxIdleConns() 来实现。
// 如果需要设置最大打开连接数，则可以使用 engine.SetMaxOpenConns() 来实现。
// 如果需要设置连接的最大生存时间，则可以使用 engine.SetConnMaxLifetime() 来实现。
func connectDb04() {
	var dns string = "root:root123@tcp(127.0.0.1:3306)/xorm1?charset=utf8mb4&parseTime=True&loc=Local"
	engine, err := xorm.NewEngine("mysql", dns)
	if err != nil {
		panic(err)
	}
	err = engine.Ping()
	if err != nil {
		panic(err)
	}

	//连接池
	engine.SetMaxOpenConns(10)
	engine.SetMaxIdleConns(10)
	engine.SetConnMaxLifetime(1000 * 10)

	defer engine.Close()

	//打印日志到控制台
	engine.ShowSQL(true)
	engine.Logger().SetLevel(log.LOG_DEBUG)

	//将日志保存到文件
	f, err := os.Create("sql.log")
	if err != nil {
		println(err.Error())
		return
	}
	engine.SetLogger(log.NewSimpleLogger(f))
}
